package vcp.client.GUI.mvc.controller;

import javax.swing.SwingUtilities;

import org.joda.time.DateTime;

import vcp.client.GUI.mvc.model.UIAbstractModel;
import vcp.client.GUI.mvc.model.UISiteMapModel;
import vcp.client.GUI.mvc.view.UIAbstractView;
import vcp.client.GUI.mvc.view.UISiteMapView;
import vcp.client.interfaces.ICommand;
import vcp.client.utility.Common.UserNotification;
import vcp.client.utility.UtilityHelper;
import vcp.entity.Site;
import vcp.entity.Worker;
import vcp.enums.PopUpMessageType;
import vcp.enums.Screen;

/**
 * 
 * @author VCP team
 *         <p>
 *         Site map controller
 *         </p>
 */
public class UISiteMapController extends UIAbstractController implements ICommand
{
	/** reference to model **/
	private final UISiteMapModel model;
	/** reference to view **/
	private final UISiteMapView view;

	/**
	 * 
	 * @param uiSiteMapView
	 *            instance of site map view
	 * @param uiSiteMapModel
	 *            instance of site map model
	 */
	public UISiteMapController ( UISiteMapView uiSiteMapView, UISiteMapModel uiSiteMapModel )
	{
		super(Screen.SITE_MAP);
		this.model = uiSiteMapModel;
		this.view = uiSiteMapView;

		this.setupListeners();
	}

	// ****************************************************************************************************************************
	// Private methods ***
	// ****************************************************************************************************************************
	/**
	 * check if the screen is now appear
	 * 
	 * @param newSite
	 * @return true if specific site on screen
	 */
	private boolean isSpecificSiteOnScreen ( Site newSite )
	{
		return newSite.getSite() == this.view.getCurrentSiteEnum();
	}

	/**
	 * drop the GUI and reload it again as new
	 * 
	 * @param requestedSite
	 */
	private synchronized void dropAndReloadGUI ( Site requestedSite )
	{
		this.view.clearView();
		this.view.loadParkingMatrix(requestedSite.getParkingMatrix());
	}

	/**
	 * prepare the site map to view
	 */
	private void prepareSiteMap ()
	{
		this.view.loadSitesOptions(this.model.getWorker().getSitesOptions());
		this.view.loadEditableStatusesOptions(this.model.getWorker().getLotEditableStatuses());

		this.view.setSitesOptionEnabled(this.model.getWorker().getSitesOptionsEnable());

		boolean hasEditPrivlige = this.model.getWorker().hasEditingPrivlige();
		this.view.setEditableStatusesEnabled(hasEditPrivlige);
		this.view.showLowerMenuPanel(hasEditPrivlige);
		this.view.showSaveButton(this.model.getWorker().canSaveToPdf());

		Site firstSite = this.model.getSites().get(0);
		this.dropAndReloadGUI(firstSite);
	}

	// ****************************************************************************************************************************
	// UIAbstractController methods ***
	// ****************************************************************************************************************************
	@Override
	public UIAbstractView getView ()
	{
		return this.view;
	}

	@Override
	public UIAbstractModel getModel ()
	{
		return this.model;
	}

	@Override
	public void uploadDataContext ( Object data )
	{
		if ( data instanceof Worker )
		{
			this.flashData();
			Worker worker = (Worker) data;
			this.model.setWorker(worker);

			this.prepareSiteMap();
			this.model.shouldRegisterForUpdates();
			this.view.setOnScreen(true);
		}
	}

	@Override
	public void clearMVC ()
	{
		this.view.setOnScreen(false);
	}

	@Override
	public void flashData ()
	{
		this.view.clearView();
		this.model.clearModel();
	}

	@Override
	protected void setupListeners ()
	{
		super.setupListeners();
		this.view.setCommandExecutor(this);
	}

	// ****************************************************************************************************************************
	// IControllerViewDelegate methods ***
	// ****************************************************************************************************************************
	@Override
	public void onButtonPress ( Object object )
	{
		// a reload required
		if ( object == null )
		{
			Site site = this.model.getSiteOnDemand(this.view.getCurrentSiteEnum());
			this.dropAndReloadGUI(site);
		}
		// site save in DB required
		else if ( object instanceof Site )
		{
			Site site = (Site) object;
			this.model.saveSiteRequest(site);
		}
	}

	// ****************************************************************************************************************************
	// IControllerModelDelegate methods ***
	// ****************************************************************************************************************************
	@Override
	public void updateControllerDelegateWithData ( Object newData )
	{
		this.parentDelegate.notifyOnDataUpdate(this.model.getWorker());
		if ( this.view.isOnScreen() )
		{
			if ( newData instanceof Site )
			{
				final Site newSite = (Site) newData;
				if ( this.isSpecificSiteOnScreen(newSite) )
				{
					this.parentDelegate.showPopUpMessage(String.format(UserNotification.__VALUE__IS_UPDATED, newSite.getSiteName()), PopUpMessageType.INFORMATION);
					SwingUtilities.invokeLater(new Runnable()
						{
							@Override
							public void run ()
							{
								UISiteMapController.this.dropAndReloadGUI(newSite);
							}
						});
				}
			}
			else if ( newData instanceof String )
			{
				String notification = (String) newData;
				this.parentDelegate.showPopUpMessage(notification, PopUpMessageType.INFORMATION);
			}
		}
	}

	// ****************************************************************************************************************************
	// ICommand methods ***
	// ****************************************************************************************************************************
	@Override
	public boolean canExecute ()
	{
		return this.model.getWorker().canSaveToPdf();
	}

	@Override
	public void execute ()
	{
		Site site = this.model.getSiteOnDemand(this.view.getCurrentSiteEnum());
		DateTime currentTimeStamp = this.parentDelegate.requestCurrentClientDateTime();

		boolean success = UtilityHelper.getUtilityHelperInstance().getPdfGenerator().saveToPDF(site, currentTimeStamp);

		String result = success
								? "Successfully saved to pdf"
								: "Problems with save";
		this.parentDelegate.showPopUpMessage(result, PopUpMessageType.INFORMATION);
	}

}
